import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
from datetime import datetime

# ---------------------- 1. 路径与样式设置 ----------------------
# 使用您提供的准确数据路径
ROOT_DIR = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验"
DATA_PATH = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\data\erp_order_data.xlsx"
SAVE_PATH = os.path.join(ROOT_DIR, "results", "26_柱形圆图表.png")

# 设置统一的视觉风格
plt.rcParams.update({
    'font.sans-serif': ['SimHei'],
    'axes.unicode_minus': False,
    'axes.facecolor': '#1A1A2E',
    'figure.facecolor': '#1A1A2E',
    'text.color': 'white',
    'xtick.color': 'white',
    'ytick.color': 'white',
    'grid.color': '#4A4A6A',
    'axes.linewidth': 1.5
})


# ---------------------- 2. 数据处理 ----------------------
def process_sales_data(df):
    """处理销售数据，计算区域销量和同比增长率"""
    # 确保订单时间是日期格式
    df['order_time'] = pd.to_datetime(df['order_time'])

    # 2025年数据（当前年份）
    current_year = datetime.now().year
    current_half_year = df[(df['order_time'].dt.year == current_year) &
                           (df['order_time'].dt.month <= 6)]

    # 2024年数据（前一年）
    prev_half_year = df[(df['order_time'].dt.year == current_year - 1) &
                        (df['order_time'].dt.month <= 6)]

    # 创建区域映射
    region_map = {
        '华东': ['上海市', '江苏省', '浙江省', '安徽省', '福建省', '江西省', '山东省'],
        '华南': ['广东省', '广西壮族自治区', '海南省'],
        '华北': ['北京市', '天津市', '河北省', '山西省', '内蒙古自治区'],
        '西南': ['重庆市', '四川省', '贵州省', '云南省', '西藏自治区'],
        '西北': ['陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区'],
        '中南': ['河南省', '湖北省', '湖南省']
    }

    # 将省份映射到区域
    def map_to_region(province):
        for region, provinces in region_map.items():
            if province in provinces:
                return region
        return '其他'

    # 添加区域列
    df['region'] = df['province'].apply(map_to_region)

    # 按区域汇总2025年上半年销售金额
    current_sales = current_half_year.groupby('region')['paid_amount'].sum().reset_index()
    current_sales.columns = ['region', 'current_sales']

    # 按区域汇总2024年上半年销售金额
    prev_sales = prev_half_year.groupby('region')['paid_amount'].sum().reset_index()
    prev_sales.columns = ['region', 'prev_sales']

    # 合并数据
    region_sales = pd.merge(current_sales, prev_sales, on='region', how='outer').fillna(0)

    # 计算同比增长率
    region_sales['growth_rate'] = region_sales.apply(
        lambda x: (x['current_sales'] - x['prev_sales']) / x['prev_sales'] if x['prev_sales'] > 0 else 0,
        axis=1
    )

    # 过滤掉"其他"区域
    region_sales = region_sales[region_sales['region'] != '其他']

    # 按2025年销量排序
    region_sales = region_sales.sort_values('current_sales', ascending=False)

    return region_sales


try:
    # 加载ERP订单数据
    df = pd.read_excel(DATA_PATH)
    print(f"成功加载ERP订单数据，总记录数: {len(df)}")

    # 处理销售数据
    region_sales = process_sales_data(df)

    # 提取数据
    regions = region_sales['region'].tolist()
    sales = region_sales['current_sales'].round(0).astype(int).tolist()
    growth_rates = (region_sales['growth_rate'] * 100).round(0).astype(int).tolist()

    # 找出销量最高的区域
    max_idx = np.argmax(sales)
    max_region = regions[max_idx]
    max_sales = sales[max_idx]

    # 找出同比增长率最高的两个区域
    growth_sorted = sorted(zip(regions, growth_rates), key=lambda x: x[1], reverse=True)
    max_growth_regions = [region for region, _ in growth_sorted[:2]]

except Exception as e:
    print(f"处理数据失败: {e}")
    # 使用预设数据
    regions = ['华东', '华南', '华北', '西南', '西北', '中南']
    sales = [96657, 26093, 24586, 32460, 30840, 28351]
    growth_rates = [12, 25, 16, 21, 18, 19]

    # 计算最大值
    max_idx = np.argmax(sales)
    max_region = regions[max_idx]
    max_sales = sales[max_idx]

    # 找出同比增长率最高的两个区域
    growth_sorted = sorted(zip(regions, growth_rates), key=lambda x: x[1], reverse=True)
    max_growth_regions = [region for region, _ in growth_sorted[:2]]

# ---------------------- 3. 绘制柱形圆图表 ----------------------
# 创建图形
fig, ax = plt.subplots(figsize=(14, 9))
ax.set_facecolor('#1A1A2E')

# 设置x轴位置
x_pos = np.arange(len(regions))
bar_width = 0.6

# 柱形颜色（红色系）
bar_colors = ['#E56A72', '#FF6B6B', '#FF7878', '#FF8585', '#FF9292', '#FF9F9F']

# 绘制柱形图
bars = ax.bar(x_pos, sales, width=bar_width,
              color=bar_colors,
              edgecolor='white',
              linewidth=2,
              alpha=0.9,
              zorder=2,
              label='销量')

# 在柱形顶部添加蓝色圆形（散点图）
circle_size = 1000  # 圆形大小
circle_colors = ['#4BB5C2', '#4BB5C2', '#4BB5C2', '#4BB5C2', '#4BB5C2', '#4BB5C2']

# 修正：调整圆形位置，确保不会与柱形内文字重叠
for i, (x, value) in enumerate(zip(x_pos, sales)):
    # 计算圆形中心位置（在柱形顶部上方）
    circle_y = value * 1.05

    # 绘制圆形
    circle = ax.scatter(x, circle_y,
                        s=circle_size,
                        color=circle_colors[i],
                        edgecolor='white',
                        linewidth=2.5,
                        alpha=0.95,
                        zorder=3)

    # 在圆形内添加增长率文本 - 修正：使用正确的增长率值
    ax.text(x, circle_y,
            f'{growth_rates[i]}%',
            ha='center', va='center',
            fontsize=14, fontweight='bold',
            color='white', zorder=4)

# 在柱形内部添加销量数值 - 修正：位置调整避免与圆形重叠
for i, (bar, value) in enumerate(zip(bars, sales)):
    # 位置调整到柱形80%高度处
    bar_y = value * 0.8
    ax.text(bar.get_x() + bar.get_width() / 2, bar_y,
            f'{value:,}',
            ha='center', va='center',
            fontsize=14, fontweight='bold',
            color='white',
            bbox=dict(boxstyle='round,pad=0.3', facecolor='#2C3E50', alpha=0.8, edgecolor='none'),
            zorder=3)

# 设置x轴标签
ax.set_xticks(x_pos)
ax.set_xticklabels(regions, fontsize=14, fontweight='bold', color='white')

# 标题与副标题
ax.set_title('各区域上半年销量及同比增长比',
             fontsize=24, fontweight='bold', pad=30, color='white')
ax.text(0.5, 0.85,
        f'{max_region}整体销量最好，达到{max_sales}，{", ".join(max_growth_regions)}同比去年增长最多',
        ha='center', va='center', transform=ax.transAxes,
        fontsize=18, color='#E0E0E0', fontweight='bold')

# 设置y轴范围
max_value = max(sales) * 1.3
ax.set_ylim(0, max_value)

# 设置网格
ax.grid(axis='y', alpha=0.3, linestyle='--', color='#4A4A6A')
ax.set_axisbelow(True)

# 隐藏坐标轴边框，只保留底部x轴
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_color('#4A4A6A')
ax.spines['bottom'].set_color('#4A4A6A')

# 添加数据来源
current_date = datetime.now().strftime('%Y.%m.%d')
ax.text(0.5, 0.05,
        f'*注：数据来源于公司销售系统，统计日期截至{current_date}',
        ha='center', va='center', transform=ax.transAxes,
        fontsize=12, color='#B0B0B0', alpha=0.7)

# 确保布局紧凑
plt.tight_layout(rect=[0, 0.05, 1, 0.95])

# 确保结果目录存在
os.makedirs(os.path.dirname(SAVE_PATH), exist_ok=True)

# 保存图片
plt.savefig(SAVE_PATH, dpi=300, bbox_inches='tight', facecolor='#1A1A2E', edgecolor='none')
plt.close()

print("\n✅ 柱形圆图表生成成功！")
print(f"📁 保存路径：{SAVE_PATH}")
print("📊 图表内容：")
print(f"- 数据时间范围：2025年上半年")
print(f"- 区域数量：{len(regions)}")
print(f"- 最高销量区域：{max_region}（{max_sales}）")
print(f"- 最高增长率区域：{growth_sorted[0][0]}（{growth_sorted[0][1]}%）")
print("🎨 图表特点：")
print("  • 红色柱形表示销量")
print("  • 蓝色圆形表示同比增长率")
print("  • 圆形位置调整在柱形顶部上方，避免与销量数值重叠")
print("  • 正确显示同比增长率百分比")